<?php
namespace app\backend\service;
use app\backend\model\MenuModel;
use app\backend\model\RoleModel;
use app\common\RootException;
use app\common\RootService;
use app\backend\validate\RoleValidate;
use app\backend\model\AdminModel;

class RoleService extends RootService
{
    /**
     * 角色列表
     * @param array $params
     * @return array
     * @throws \app\common\RootException
     * @throws \think\db\exception\DbException
     */
    public function lists(array $params)
    {
        $adminInfo = adminInfo();
        // 数据源
        $roleList = $this->RoleModel($params)->order('rol.id desc')->paginate($params['limit'])->toArray();
        // 数据处理
        empty($roleList) || array_walk($roleList['data'], function (&$row) use ($adminInfo) {
            $row['handle'] = $row['admin_id'] == $adminInfo['id'] ? 1 : 0;
            $row['del'] = $row['id'] == $adminInfo['role_id'] ? 0 : 1;
            $row['real_name'] .= "【{$row['admin_name']}】";
        });
        return $roleList;
    }

    /**
     * 添加角色
     * @param array $params
     * @return array
     * @throws \app\common\RootException
     */
    public function add(array $params)
    {
        // 数据校验
        $this->baseVerify($params);
        // 数据处理
        $insertData = ['admin_id' => adminInfo('id'), 'role_name' => $params['roleName'], 'remark' => $params['remark'],
            'menu_ids' => join(',', $params['authList'])];
        // 新增操作
        RoleModel::create($insertData) || $this->errorException('添加失败');
        return ['msg' => '添加成功', 'preload' => true];
    }

    /**
     * 详情
     * @param int $roleId
     * @return array
     * @throws RootException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function info(int $roleId)
    {
        if (!$roleInfo = RoleModel::where(['id' => $roleId])->find()) {
            throw new RootException('角色不存在');
        }
        return $roleInfo->toArray();
    }

    /**
     * 编辑角色
     * @param array $params
     * @return array
     * @throws RootException
     */
    public function edit(array $params)
    {
        // 数据校验
        $this->baseVerify($params, 'edit');
        // 更新参数
        $updateData = ['remark' => $params['remark']];
        // 系统管理员更新
        if (!in_array(RoleModel::where(['id' => $params['roleId']])->value('menu_ids'), ['*'])) {
            $updateData['menu_ids'] = join(',', $params['authList']);
        }
        // 数据更新
        RoleModel::where(['id' => $params['roleId']])->update($updateData) || $this->errorException('修改失败');
        return ['code' => 0, 'msg' => '修改成功', 'preload' => true];
    }

    /**
     * 对选中的菜单进行整合
     * @param int $roleId
     * @return array
     * @throws RootException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function checkAuth(int $roleId)
    {
        $menuIds = RoleModel::where(['id' => $roleId])->value('menu_ids');
        return (new AuthService())->checkedAuth(explode(',', $menuIds));
    }

    /**
     * 设置角色
     * @param array $params
     * @return array
     * @throws RootException
     */
    public function setAuth(array $params)
    {
        // 数据校验
        $this->baseVerify($params, 'set');
        // 入库操作
        $updateData = ['admin_id' => adminInfo('id'), 'role_name' => $params['roleName'], 'menu_ids' =>
            join(',', array_column($params['authList'], 'id')), 'remark' => $params['remark']];
        if (RoleModel::where(['id' => $params['roleId']])->update($updateData)) {
            return ['code' => 0, 'msg' => '设置成功', 'preload' => true];
        }
        $this->errorException('设置失败');
    }

    /**
     * 删除角色
     * @param int $roleId
     * @return array
     * @throws RootException
     */
    public function del(int $roleId)
    {
        try {
            RoleModel::where(['id' => $roleId])->delete();
            return ['code' => 0, 'msg' => '删除成功', 'reload' => true];
        } catch (\Exception $e) {
            throw new RootException('删除失败:' . $e->getMessage());
        }
    }

    /**
     * 数据校验
     * @param array $params
     * @param string $scene
     * @throws RootException
     */
    protected function baseVerify(array $params, string $scene = 'add')
    {
        // 基础校验
        $validate = new RoleValidate();
        $validate->scene($scene)->check($params) || $this->errorException($validate->getError());
        // 角色名称校验
        if (in_array($scene, ['add'])) {
            $where = [['admin_id', '=', adminInfo('id')], ['role_name', '=', $params['roleName']]];
            RoleModel::where($where)->count() && $this->errorException("已存在【{$params['roleName']}】相同的角色名!");
        }
    }


    /**
     * 角色模型
     * @param array $params
     * @return RoleModel
     * @throws \app\common\RootException
     */
    protected function RoleModel(array $params)
    {
        // 基本条件
        $where = [['a.id', 'in', selfSubAdminList('id', true)], ['rol.id', '<>', 'a.role_id'], ['rol.forbid', '=', 1]];
        // 商户筛选
        empty($params['roleName']) || $where[] = ['rol.role_name', 'like', $params['roleName'] . '%'];
        // 用户名|姓名筛选
        empty($params['adminName']) || $where[] = ['a.admin_name|a.real_name', 'like', $params['adminName'] . '%'];
        // 筛选字段
        $fields = ['rol.role_name', 'rol.remark', 'rol.create_time', 'rol.id', 'a.admin_name', 'a.merchant_id', 'rol.admin_id',
            'a.real_name'];
        // 筛选结果
        return AdminModel::alias('a')->join(['sys_role' => 'rol'], 'a.id = rol.admin_id', 'left')->where($where)->field($fields);
    }
}